#define _USE_MATH_DEFINES

#include "Car.h"
#include <gl/glut.h>

Car::Car()
{
	position.x = 0;
	position.y = 0;
	position.z = 0;
}

Car::Car(const char *points, const char *faces, const char *textures, const char *textureindex)
{
	position.x = 0;
	position.y = 0;
	position.z = 0;
	direction.x = 0;
	direction.y = 0;
	direction.z = 5;
	turn = 0;

	readPoints(points);
	readFaces(faces);
	readTexture(textures);
	readTextureIndex(textureindex);
}

bool Car::readPoints(const char *points)
{
	std::fstream file;
	file.open(points, std::ios::in);
	if (!file)
		return false;

	double x,y,z;
	while(!file.eof())
	{
		file >> x >> y >> z;
		Point tmp;
		tmp.x = x;
		tmp.y = y;
		tmp.z = z;
		this->points.push_back(tmp);
	}
	return true;
}

bool Car::readFaces(const char *faces)
{
	std::fstream file;
	file.open(faces,std::ios::in);
	if (!file)
		return false;

	int a,b,c;
	while(!file.eof())
	{
		file >> a >> b >> c;
		Triangle t;
		t.index1 = a-1;
		t.index2 = b-1;
		t.index3 = c-1;
		this->faces.push_back(t);
	}

	return true;
}

bool Car::readTexture(const char *textures)
{
	std::fstream file;
	file.open(textures,std::ios::in);
	if (!file)
		return false;

	double a,b,c;
	while(!file.eof())
	{
		file >> a >> b >> c;
		Texture t;
		t.r = a;
		t.g = b;
		t.b = c;
		this->textures.push_back(t);
	}

	return true;
}

bool Car::readTextureIndex(const char *texturesindex)
{
	std::fstream file;
	file.open(texturesindex,std::ios::in);
	if (!file)
		return false;

	int a,b,c;
	while(!file.eof())
	{
		file >> a >> b >> c;
		TextureIndex t;
		t.index1 = a-1;
		t.index2 = b-1;
		t.index3 = c-1;
		this->textureindex.push_back(t);
	}

	return true;
}

void Car::Update()
{
	
}

void Car::Draw()
{
	std::vector<Point> show_points;
	
	GLfloat ambient_and_diffuse[] = {0.5f, 0.0f, 0.2f, 1.0f};
	GLfloat specular[] = {0.0f,0.0f,1.0f,1.0f};
	GLfloat emission[] = {0.0f, 0.0f, 0.0f ,1.0f};
	GLfloat shininess = 20.0f;

	::glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ambient_and_diffuse);
	::glMaterialfv(GL_FRONT, GL_SPECULAR, specular);
	::glMaterialfv(GL_FRONT, GL_EMISSION, emission);
	::glMaterialf(GL_FRONT, GL_SHININESS, shininess);
	
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	::glBegin(GL_TRIANGLES);

	for (int i=0; i<points.size(); i++)
	{
		Point tmp;
		double x = points[i].x;
		double z = points[i].z;
		tmp.x = x * cos(turn) - z * sin(turn) + position.x;
		tmp.z = z * cos(turn) + x *sin(turn) + position.z;
		tmp.y = points[i].y + position.y;

		show_points.push_back(tmp);
	}

	for (int i=0; i<faces.size(); i++)
	{
		::glVertex3d(show_points[faces[i].index1].x, show_points[faces[i].index1].y, show_points[faces[i].index1].z);
		::glVertex3d(show_points[faces[i].index2].x, show_points[faces[i].index2].y, show_points[faces[i].index2].z);
		::glVertex3d(show_points[faces[i].index3].x, show_points[faces[i].index3].y, show_points[faces[i].index3].z);
	}
	::glEnd();

}

void Car::Forward()
{
	//for (int i=0; i<points.size(); i++)
	//{
		//points[i].x += direction.x;
		//points[i].y += direction.y;
		//points[i].z += direction.z;
	//}
	position.x += direction.x;
	position.y += direction.y;
	position.z += direction.z;
}

void Car::Back()
{
	/*for (int i=0; i<points.size(); i++)
	{
		points[i].x -= direction.x;
		points[i].y -= direction.y;
		points[i].z -= direction.z;
	}*/
	position.x -= direction.x;
	position.y -= direction.y;
	position.z -= direction.z;
}

void Car::TurnRight()
{
	turn += 0.1;
	direction.x = -5 * sin(turn);
	direction.z = 5 * cos(turn);
}

void Car::TurnLeft()
{
	turn -= 0.1;
	direction.x = -5 * sin(turn);
	direction.z = 5 *cos(turn);
}